# -*- coding: utf-8 -*-

from api import api, ERROR_PIN, GlobalError
from flask import jsonify, request
from model.pin import Pin
from model.studio import Studio
from util.send_email import send_email
from werkzeug.exceptions import NotFound
from config import B_WEB_URL

import random
from time import time

SEND_INTERVAL = 60  #对相同邮箱两次发送邮件的时间间隔

class Error:
    EMAIL_NOT_EXIST = {
        'err': ERROR_PIN + 1,
        'msg': 'Email Not Exist'
    }
    EMAIL_INVALID = {
        'err': ERROR_PIN + 2,
        'msg': 'Email Invalid'
    }
    SEND_EMAIL_FAILURE = {
        'err': ERROR_PIN + 3,
        'msg': 'Send Email Failure'
    }
    PIN_AUTH_FAILURE = {
        'err': ERROR_PIN + 4,
        'msg': 'PIN Auth Failure'
    }
    SEND_TOO_FREQUENTLY = {
        'err': ERROR_PIN + 5,
        'msg': 'Send Email Too Frequently'
    }
    

def create_token():
    # 生成20位随机字符串
    all_char = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    random_str = reduce((lambda x, y: x + y), random.sample(all_char, 20))
    try:
        Pin.get({
            Pin.Field.code: random_str
        })
        create_token()
    except NotFound:
        return random_str


@api.route('/pin', methods=['POST'])
def send_PIN():
    """
## 对特定邮箱地址发送随机生成的字符串

    POST /api/pin

Parameters:

* `email` (string, required) - email of user 

    """

    email = request.form.get('email', None)

    if email is None:
        return jsonify(stat=0, **Error.EMAIL_INVALID), 403

    if email is not None:
        try:
            user = Studio.get({
                Studio.Field.email: email
            })
        except NotFound:
            return jsonify(stat=0, **Error.EMAIL_NOT_EXIST), 403


    random_str = create_token()
    link = (B_WEB_URL + "/resetPassword.html?confirmation_token=%s") % random_str
    email_content = u"你好：%s！你需要点击以下链接来重置你的密码：%s" % (email, link)
    
    try:
        user_pin = Pin.get({
            Pin.Field.email: email
        })
        if user_pin.data.get(Pin.Field.createTime, '') > int(time()) - SEND_INTERVAL:
            return jsonify(stat=0, **Error.SEND_TOO_FREQUENTLY), 403
        else:
            user_pin.update({
                '$set': {
                    Pin.Field.code: random_str,
                    Pin.Field.createTime: int(time())
                }
            })
    except NotFound:
        Pin.create_pin(email, random_str)


    stat = send_email([email], u"重置密码", email_content)

    if stat:
        return jsonify(stat=1)
    else:
        return jsonify(stat=0, **Error.SEND_EMAIL_FAILURE), 403


@api.route('/pin_verification', methods=['POST'])
def reset_password():
    """
## 重置密码

    POST /api/pin_verification?confirmation_token=...

Parameters:

* `newPassword` (string, required) - new password 
* `confirmation_token` (string, required) - the token in url
    """

    confirmation_token = request.args.get('confirmation_token', None)
    new_password = request.form.get('newPassword', None)

    Pin.delete_expired_pin()
    
    try:
        user_pin = Pin.get({
            Pin.Field.code: confirmation_token
        })
    except NotFound:
        return jsonify(stat=0, **Error.PIN_AUTH_FAILURE), 403
    
    try:
        user = Studio.get({
            Studio.Field.email: user_pin.data.get(Pin.Field.email, '')
        })
    except NotFound:
        return jsonify(stat=0, **Error.EMAIL_INVALID), 403

    new_hash_password = Studio.get_hashed_password(new_password)
    user.update({
        '$set': {
            Studio.Field.password: new_hash_password
        }
    })


    #用完失效
    Pin.remove({    
        Pin.Field._id: user_pin.data.get(Pin.Field._id, '')
    })

    return jsonify(stat=1)

